﻿using KG.Neo4j;
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;
using JsonHelper;
using Newtonsoft.Json;
using System.Linq;

namespace KG.SystemService
{
    /// <summary>
    /// 节点服务
    /// </summary>
    public class NodeService
    {
        //public NodeService(IHttpContextAccessor httpContextAccessor)
        //{

        //}
        public Neo4jRepository _neo4jRepository=new Neo4jRepository("", "neo4j://localhost:7687", "neo4j", "fdbsn0607.");
        
        /// <summary>
        /// 添加节点
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public NodeDTO.OutputId AddNode(NodeDTO.InputAdd req)
        {
            try
            {
                req.Check();
                //反序列化Properties
                dynamic properties = JsonUtils.Deserialize(req.Properties);
                Dictionary<string, string> properties1 = JsonUtils.Deserialize<Dictionary<string, string>>(properties.ToString());
                var labels = req.Labels;
                string id = _neo4jRepository.CreateSingleNode(labels, properties1).Result;

                return new NodeDTO.OutputId { id = id};
            }
            catch (Exception)
            {
                throw new Exception("添加节点失败");
            }
        }
        /// <summary>
        /// 删除节点
        /// </summary>
        /// <returns></returns>
        public NodeDTO.OutputId DeleteNode(NodeDTO.InputDelete req)
        {
            try
            {
                req.Check();
                long id = long.Parse(req.id);
                string condtion = $"id({_neo4jRepository.Key})={id}";
                _neo4jRepository.DeleteNode(condtion);
                return new NodeDTO.OutputId { id = req.id };
            }
            catch (Exception)
            {
                throw new Exception("删除节点失败");
            }
        }
        /// <summary>
        /// 更新节点
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public NodeDTO.OutputId UpdateNode(NodeDTO.InputUpdate req)
        {
            try
            {
                req.Check();
                string condtion = $"id({_neo4jRepository.Key})={req.id}";
                //找到标签，并remove
                var a = _neo4jRepository.SelectNodeLabel(condtion).Result;
                dynamic Labelslists = JsonUtils.Deserialize(a.Item1.FirstOrDefault());
                string[] Labels = JsonUtils.Deserialize<string[]>(Labelslists.ToString());
                string removestrs = string.Join(":", Labels);
                removestrs = $"n:{removestrs}";
                //待更新的属性
                dynamic properties = JsonUtils.Deserialize(req.Properties);
                Dictionary<string, string> properties1 = JsonUtils.Deserialize<Dictionary<string, string>>(properties.ToString());
                string setStr = "";
                foreach (var v in properties1)
                {
                    string propertyBuilder = $"{ _neo4jRepository.Key}.{v.Key}=\"{v.Value}\",";
                    setStr += propertyBuilder;
                }
                //待更新的标签
                string addlabels = string.Join(":",req.Labels);
                setStr += $"{_neo4jRepository.Key}:{addlabels}";
                string removestr = "";
                foreach (var item in req.deleteProperty)
                {
                    string removeBulider = $"{ _neo4jRepository.Key}.{item},";
                    removestr += removeBulider;
                }
                removestr += removestrs;
                _neo4jRepository.UpdateNode(condtion, removestr, setStr);
                return new NodeDTO.OutputId { id = req.id };
            }
            catch (Exception)
            {
                throw new Exception("更新节点失败");
            }
        }
        /// <summary>
        /// 根据标签查询节点列表
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public NodeDTO.OutputLoad LoadNode(NodeDTO.InputLoad req)
        {
            try
            {
                var datas = new List<NodeInfo>();
                List<string> nodeList = new List<string>();
                //模糊检索标签
                if (req.loadType==0)
                {
                    nodeList = _neo4jRepository.LoadNodeByLabel(req.key, req.limit).Result;
                    for (int i = 0; i < nodeList.Count; i++)
                    {
                        //解析json
                        dynamic node = JsonUtils.Deserialize(JsonUtils.Deserialize(nodeList[i]).ToString());
                        Data data1 = new Data
                        {
                            id = node.id.ToObject<string>(),
                            name = node.Name.ToObject<string>()
                        };
                        NodeInfo nodeInfo = new NodeInfo
                        {
                            group = "nodes",
                            data = data1,
                            classes = node.Color.ToObject<string>()
                        };
                        datas.Add(nodeInfo);
                    }
                }
                else//检索属性
                {
                    nodeList = _neo4jRepository.LoadNodeByProperties(req.key,req.property, req.limit).Result;
                    for (int i = 0; i < nodeList.Count; i++)
                    {
                        //解析json
                        dynamic node = JsonUtils.Deserialize(JsonUtils.Deserialize(nodeList[i]).ToString());
                        Data data1 = new Data
                        {
                            id = node.id.ToObject<string>(),
                            name = node.Name.ToObject<string>()
                        };
                        NodeInfo nodeInfo = new NodeInfo
                        {
                            group = "nodes",
                            data = data1,
                            classes = node.Color.ToObject<string>()
                        };
                        datas.Add(nodeInfo);
                    }
                }
                return new NodeDTO.OutputLoad {data= datas, limit = req.limit,total = datas.Count};
            }
            catch (Exception ex)
            {
                throw new Exception("加载节点失败"+ex.Message);
            }
        }
        /// <summary>
        /// 查询单个节点信息
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public NodeDTO.OutputGet GetNode(NodeDTO.InputGet req)
        {
            try
            {
                req.check();
                string condtion = $"id({_neo4jRepository.Key})={req.id}";
                var a = _neo4jRepository.SelectNodeLabel(condtion).Result;
                //找到标签
                dynamic Labelslists = JsonUtils.Deserialize(a.Item1.FirstOrDefault());
                string[] Labels = JsonUtils.Deserialize<string[]>(Labelslists.ToString());
                //找到属性
                dynamic b = JsonUtils.Deserialize(a.Item2[0]);
                Dictionary<string, string> properties1 = JsonUtils.Deserialize<Dictionary<string, string>>(b.ToString());
                SystemService.NodeDTO.Data data = new SystemService.NodeDTO.Data
                {
                    id = req.id,
                    labels = Labels,
                    properties = properties1
                };
                return new NodeDTO.OutputGet {group = "nodes",data = data};
            }
            catch (Exception)
            {
                throw new Exception("获取节点详情失败");
            }
        }
        /// <summary>
        /// 加载节点标签
        /// </summary>
        /// <returns></returns>
        public NodeDTO.OutputLabelLoad LabelLoad()
        {
            try
            {
                var allLabels =  _neo4jRepository.SelectLabels().Result;

                return new NodeDTO.OutputLabelLoad { labels = allLabels };
            }
            catch (Exception)
            {
                throw new Exception("加载节点标签失败");
            }
        }
        /// <summary>
        /// 条件查询
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public NodeDTO.OutputLoad ComplexLoad(NodeDTO.InputComplexLoad req)
        {
            try
            {
                var datas = new List<NodeInfo>();
                string labels = string.Join(":", req.labelList);
                var nodeList = _neo4jRepository.ComplexLoad(labels,req.limit,req.cypher).Result;
                for (int i = 0; i < nodeList.Count; i++)
                {
                    //解析json
                    dynamic node = JsonUtils.Deserialize(JsonUtils.Deserialize(nodeList[i]).ToString());
                    Data data1 = new Data
                    {
                        id = node.id.ToObject<string>(),
                        name = node.Name.ToObject<string>()
                    };
                    NodeInfo nodeInfo = new NodeInfo
                    {
                        group = "nodes",
                        data = data1,
                        classes = node.Color.ToObject<string>()
                    };
                    datas.Add(nodeInfo);
                }
                return new NodeDTO.OutputLoad { limit = req.limit,data = datas,total = datas.Count };
            }
            catch (Exception)
            {
                throw new Exception("条件检索失败");
            }
        }
        public string DeleteAllNode()
        {
            try
            {
                _neo4jRepository.DeleteAllNode();
                return "已清空数据库";
            }
            catch (Exception)
            {
                throw new Exception("清库失败");
            }
        }
    }
}
